#!/bin/sh

# run_radmind: Checks for Radmind updates and applies them as necesary.

export PATH=/bin:/sbin:/usr/bin

# Import common U-M functions.
. /etc/um-common.sh

# Import Radmind defaults
. /etc/radmind.defaults

# Declarations
FSDIFF="/usr/local/bin/fsdiff"
KTCHECK="/usr/local/bin/ktcheck"
LAPPLY="/usr/local/bin/lapply"
POSTAPPLY_PATH="/private/var/radmind/postapply"
PREAPPLY_PATH="/private/var/radmind/preapply"

# Main script

# If we should check with checksums, do so.
if [ -f "${CHECKSUM_FLAG}" ]; then
	CHECKSUM="-c sha1"
fi

# Check for updates. If none, exit.
updatesFound=0
echo "Checking for updates..."
iHook_Output %BEGINPOLE
${KTCHECK} -n ${CASE} ${CHECKSUM} -h ${SERVER} -w ${TLSLEVEL} 1>&2
rc=$?
iHook_Output %ENDPOLE

if [ ${rc} == 0 ]; then #no updates
	echo "No updates."
	sleep 2
	
	if [ ! -f "${RADMIND_FLAG}" ]; then # no marker file, OK to exit
		exit 0;
	else
		echo "Continuing with Radmind update..."
		sleep 2;
	fi
else
	updatesFound=1
fi

# If we get here, then either there are updates or we're running anyway.
# Touch the marker to ensure updates happen again in case of failure.
touch "${RADMIND_FLAG}"

# Create a temporary folder.
if [ -z "${TMPDIR}" ]; then
	TMPDIR="/tmp"
fi

tmpFolder="$(mktemp -dq -t radmind)"
rc=$?

if [ ${rc} != 0 ]; then # an error occurred
	echo "An error occurred creating a temporary folder."
	exit 1
fi

fsdiffOutput="${tmpFolder}/fsdiff.out"

if [ ${updatesFound} -eq 1 ]; then
	# Update command files and transcripts.
	echo "Downloading updates..."
	iHook_Output %BEGINPOLE
	${KTCHECK} -i -C ${CASE} ${CHECKSUM} -h ${SERVER} -w ${TLSLEVEL} 1>&2
	rc=$?
	iHook_Output %ENDPOLE

	# ktcheck returns 1 on non-error conditions, so test for >1
	if [ ${rc} -gt 1 ]; then
		echo "An error occurred downloading updates."
		exit 1;
	fi

	echo "Updates downloaded."
	sleep 2
fi

cd /

echo "Checking the filesystem for differences..."
iHook_Output %BEGINPOLE
${FSDIFF} -A ${CASE} ${CHECKSUM} -o "${fsdiffOutput}" -% .
rc=$?
iHook_Output %ENDPOLE

if [ ${rc} != 0 ]; then # an error occurred
	echo "An error occurred checking the filesystem for differences."
	sleep 2
	exit 1;
fi

echo "Filesystem check complete."
sleep 2

# Check to see if the resulting transcript is empty (which can happen if we pass
# tripwire).
if [ -z "${fsdiffOutput}" ]; then
	echo "No changes necessary."
	rm -f "${RADMIND_FLAG}"
	sleep 2
	exit 0
fi

# Run pre-apply scripts, but only if there are some.
c=$(ls -1 "${PREAPPLY_PATH}" | wc -l | awk '{ print $1 }')

if [ $c -gt 0 ]; then # there is at least 1 script
	echo "Running pre-apply scripts..."
	iHook_Output %BEGINPOLE
	iHook_Output %0

	# Count the pre-apply scripts to give a rough percent done estimate.
	i=0
	for script in "${PREAPPLY_PATH}"/*; do
		${script} "${fsdiffOutput}"
		i=$((i+1))
		iHook_Output %$((i*100/c)) $(basename ${script})
	done
	echo "Pre-apply scripts complete."
	sleep 2
fi

# Check again to see if the transcript is empty, just in case the pre-apply
# scripts zero it out.
if [ -z "${fsdiffOutput}" ]; then
	echo "No changes necessary."
	rm -f "${RADMIND_FLAG}"
	sleep 2
	exit 0
fi

# Apply the changes.
echo "Applying changes from server..."
iHook_Output %BEGINPOLE
${LAPPLY} -i -F ${CASE} ${CHECKSUM} -h ${SERVER} -w${TLSLEVEL} -% \
          "${fsdiffOutput}"
rc=$?
iHook_Output %ENDPOLE

if [ ${rc} != 0 ]; then # an error occurred
	echo "An error occurred applying changes."
	exit 1;
fi

# Run post-apply scripts, but only if there are some.
c=$(ls -1 "${POSTAPPLY_PATH}" | wc -l | awk '{ print $1 }')

if [ $c -gt 0 ]; then # there is at least 1 script
	echo "Running post-apply scripts..."
	iHook_Output %BEGINPOLE
	iHook_Output %0

	# Count the post-apply scripts to give a rough percent done estimate.
	i=0
	for script in "${POSTAPPLY_PATH}"/*; do
		${script}
		i=$((i+1))
		iHook_Output %$((i*100/c)) $(basename ${script})
	done
	echo "Post-apply scripts complete."
	sleep 2
fi

echo "Radmind update complete."
rm -f "${RADMIND_FLAG}"
